source('../settings/settings.R')
source('commonFunctions.R')
persons <- SELECTED_SUBJECTS

all_Drive3 <- read.csv('..//data/processed/distancewise/TT1_Drive_3_15m_15m.csv')
all_Drive3$Subject <- as.factor(all_Drive3$Subject)
all_Drive3$logPerspiration <- log(all_Drive3$Perspiration)

Acceleration Plot

computeThreshold <- function(x, xmin=min(x), xmax=max(x)) {
  x <- x[x >= xmin & x <= xmax]
  xArr <- matrix(x, nrow = 1, ncol = length(x))
  threshold <- otsu(xArr, range=c(xmin, xmax))
  return(threshold)
}
computeThresholdForAcceleration <- function(acc){
  return(computeThreshold(acc, xmin=0, xmax=20))
}
findModes <- function(x) {
  ux <- unique(x)
  ux[which.max(tabulate(match(x, ux)))]
}
acc_thresholds <- vector(mode="list", length=length(persons)) 
names(acc_thresholds) <- persons

acc_sd_thresholds <- vector(mode="list", length=length(persons)) 
names(acc_sd_thresholds) <- persons

speed_sd_thresholds <- vector(mode="list", length=length(persons)) 
names(speed_sd_thresholds) <- persons

for (p in persons) {
  pData <- all_Drive3[(all_Drive3$Subject==as.integer(p) | all_Drive3$Subject==p),]
  acc_th <- computeThresholdForAcceleration(pData$Acceleration)
  acc_th_sd <- computeThresholdForAcceleration(pData$Acc_std)
  speed_th_sd <- computeThresholdForAcceleration(pData$Speed_std)
  acc_thresholds[[p]] <- as.numeric(acc_th)
  acc_sd_thresholds[[p]] <- as.numeric(acc_th_sd)
  speed_sd_thresholds[[p]] <- as.numeric(speed_th_sd)
  
  acc_pl <- ggplot(pData, aes(x=Acceleration)) + geom_density() + geom_vline(aes(xintercept=acc_th), color="blue", linetype="dashed", size=1)
  acc_sd_pl <- ggplot(pData, aes(x=Acc_std)) + geom_density() + geom_vline(aes(xintercept=acc_th_sd), color="red", linetype="dashed", size=1)
  speed_sd_pl <- ggplot(pData, aes(x=Speed_std)) + geom_density() + geom_vline(aes(xintercept=speed_th_sd), color="red", linetype="dashed", size=1)
  
  plot(speed_sd_pl)
  print(paste0(p, " - Threshold (Acc) =", acc_th, " & (Acc SD) =", acc_th_sd, " & (Speed SD) =", acc_th_sd))
  
}
[1] "01 - Threshold (Acc) =8.2421875 & (Acc SD) =5.546875 & (Speed SD) =5.546875"
[1] "02 - Threshold (Acc) =9.9609375 & (Acc SD) =5.8203125 & (Speed SD) =5.8203125"
[1] "03 - Threshold (Acc) =9.1796875 & (Acc SD) =7.0703125 & (Speed SD) =7.0703125"
[1] "04 - Threshold (Acc) =10.1953125 & (Acc SD) =6.40625 & (Speed SD) =6.40625"
[1] "05 - Threshold (Acc) =9.9609375 & (Acc SD) =4.8046875 & (Speed SD) =4.8046875"
[1] "06 - Threshold (Acc) =10.234375 & (Acc SD) =6.4453125 & (Speed SD) =6.4453125"
[1] "07 - Threshold (Acc) =11.6015625 & (Acc SD) =7.3828125 & (Speed SD) =7.3828125"
[1] "09 - Threshold (Acc) =9.296875 & (Acc SD) =6.0546875 & (Speed SD) =6.0546875"
[1] "12 - Threshold (Acc) =9.7265625 & (Acc SD) =7.0703125 & (Speed SD) =7.0703125"
[1] "13 - Threshold (Acc) =10.5859375 & (Acc SD) =7.6171875 & (Speed SD) =7.6171875"
[1] "15 - Threshold (Acc) =9.1796875 & (Acc SD) =6.6796875 & (Speed SD) =6.6796875"
[1] "16 - Threshold (Acc) =9.5703125 & (Acc SD) =8.7109375 & (Speed SD) =8.7109375"
[1] "17 - Threshold (Acc) =9.1796875 & (Acc SD) =6.8359375 & (Speed SD) =6.8359375"
[1] "18 - Threshold (Acc) =10.9375 & (Acc SD) =6.5234375 & (Speed SD) =6.5234375"
[1] "22 - Threshold (Acc) =9.8046875 & (Acc SD) =5.6640625 & (Speed SD) =5.6640625"
[1] "24 - Threshold (Acc) =9.0234375 & (Acc SD) =7.2265625 & (Speed SD) =7.2265625"
[1] "29 - Threshold (Acc) =6.71875 & (Acc SD) =6.2109375 & (Speed SD) =6.2109375"
[1] "30 - Threshold (Acc) =8.90625 & (Acc SD) =6.5234375 & (Speed SD) =6.5234375"
[1] "31 - Threshold (Acc) =11.875 & (Acc SD) =6.2109375 & (Speed SD) =6.2109375"
[1] "32 - Threshold (Acc) =5.3515625 & (Acc SD) =7.1484375 & (Speed SD) =7.1484375"
[1] "41 - Threshold (Acc) =12.2265625 & (Acc SD) =5.8203125 & (Speed SD) =5.8203125"

mean_pp <- vector(mode="list", length=length(persons)) 
names(mean_pp) <- persons

std_pp <- vector(mode="list", length=length(persons)) 
names(std_pp) <- persons

# Mean (Turning)
mean_pp_seg0 <- vector(mode="list", length=length(persons)) 
names(mean_pp_seg0) <- persons
mean_pp_seg0_1 <- vector(mode="list", length=length(persons)) 
names(mean_pp_seg0_1) <- persons
mean_pp_seg0_2 <- vector(mode="list", length=length(persons)) 
names(mean_pp_seg0_2) <- persons
mean_pp_seg0_3 <- vector(mode="list", length=length(persons)) 
names(mean_pp_seg0_3) <- persons
mean_pp_seg0_4 <- vector(mode="list", length=length(persons)) 
names(mean_pp_seg0_4) <- persons

# Mean (Straight)
mean_pp_seg1 <- vector(mode="list", length=length(persons)) 
names(mean_pp_seg1) <- persons
mean_pp_seg2 <- vector(mode="list", length=length(persons)) 
names(mean_pp_seg2) <- persons
mean_pp_seg3 <- vector(mode="list", length=length(persons)) 
names(mean_pp_seg3) <- persons
mean_pp_seg4 <- vector(mode="list", length=length(persons)) 
names(mean_pp_seg4) <- persons
mean_pp_max <- vector(mode="list", length=length(persons)) 
names(mean_pp_max) <- persons

# SD (Turning)
std_pp_seg0 <- vector(mode="list", length=length(persons)) 
names(std_pp_seg0) <- persons
std_pp_seg0_1 <- vector(mode="list", length=length(persons)) 
names(std_pp_seg0_1) <- persons
std_pp_seg0_2 <- vector(mode="list", length=length(persons)) 
names(std_pp_seg0_2) <- persons
std_pp_seg0_3 <- vector(mode="list", length=length(persons)) 
names(std_pp_seg0_3) <- persons
std_pp_seg0_4 <- vector(mode="list", length=length(persons)) 
names(std_pp_seg0_4) <- persons

# SD (Straight)
std_pp_seg1 <- vector(mode="list", length=length(persons)) 
names(std_pp_seg1) <- persons
std_pp_seg2 <- vector(mode="list", length=length(persons)) 
names(std_pp_seg2) <- persons
std_pp_seg3 <- vector(mode="list", length=length(persons)) 
names(std_pp_seg3) <- persons
std_pp_seg4 <- vector(mode="list", length=length(persons)) 
names(std_pp_seg4) <- persons
std_pp_max <- vector(mode="list", length=length(persons)) 
names(std_pp_max) <- persons

# Acceleration Partitioning
mean_pp_HighAcc <- vector(mode="list", length=length(persons)) 
names(mean_pp_HighAcc) <- persons
mean_pp_LowAcc <- vector(mode="list", length=length(persons)) 
names(mean_pp_LowAcc) <- persons

std_pp_HighAcc <- vector(mode="list", length=length(persons)) 
names(std_pp_HighAcc) <- persons
std_pp_LowAcc <- vector(mode="list", length=length(persons)) 
names(std_pp_LowAcc) <- persons

# Accel + Segmentation
mean_pp_HighAcc1 <- vector(mode="list", length=length(persons)) 
names(mean_pp_HighAcc1) <- persons
mean_pp_LowAcc1 <- vector(mode="list", length=length(persons)) 
names(mean_pp_LowAcc1) <- persons
std_pp_HighAcc1 <- vector(mode="list", length=length(persons)) 
names(std_pp_HighAcc1) <- persons
std_pp_LowAcc1 <- vector(mode="list", length=length(persons)) 
names(std_pp_LowAcc1) <- persons

mean_pp_HighAcc2 <- vector(mode="list", length=length(persons)) 
names(mean_pp_HighAcc2) <- persons
mean_pp_LowAcc2 <- vector(mode="list", length=length(persons)) 
names(mean_pp_LowAcc2) <- persons
std_pp_HighAcc2 <- vector(mode="list", length=length(persons)) 
names(std_pp_HighAcc2) <- persons
std_pp_LowAcc2 <- vector(mode="list", length=length(persons)) 
names(std_pp_LowAcc2) <- persons

mean_pp_HighAcc3 <- vector(mode="list", length=length(persons)) 
names(mean_pp_HighAcc3) <- persons
mean_pp_LowAcc3 <- vector(mode="list", length=length(persons)) 
names(mean_pp_LowAcc3) <- persons
std_pp_HighAcc3 <- vector(mode="list", length=length(persons)) 
names(std_pp_HighAcc3) <- persons
std_pp_LowAcc3 <- vector(mode="list", length=length(persons)) 
names(std_pp_LowAcc3) <- persons

mean_pp_HighAcc4 <- vector(mode="list", length=length(persons)) 
names(mean_pp_HighAcc4) <- persons
mean_pp_LowAcc4 <- vector(mode="list", length=length(persons)) 
names(mean_pp_LowAcc4) <- persons
std_pp_HighAcc4 <- vector(mode="list", length=length(persons)) 
names(std_pp_HighAcc4) <- persons
std_pp_LowAcc4 <- vector(mode="list", length=length(persons)) 
names(std_pp_LowAcc4) <- persons

for(p in persons) {
  pData <- all_Drive3[(all_Drive3$Subject==as.integer(p) | all_Drive3$Subject==p),]
  pData_act3 <- pData[pData$Activity==3,]
  
  # Data Partitioning
  pData_seg0 <- pData[pData$Phase==0,]
  pData_seg0_1 <- pData[pData$Activity==0 & pData$Phase==0 & pData$Time > 100 & pData$Time < 200,]
  pData_seg0_2 <- pData[pData$Activity==0 & pData$Phase==0 & pData$Time > 200 & pData$Time < 300,]
  pData_seg0_3 <- pData[pData$Activity==0 & pData$Phase==0 & pData$Time > 300 & pData$Time < 400,]
  pData_seg0_4 <- pData[pData$Activity==0 & pData$Phase==0 & pData$Time > 400 & pData$Time < 500,]
  
  pData_seg1 <- pData[pData$Phase==1 & pData$Activity==3 & pData$Time < 110,]
  pData_seg2 <- pData[pData$Phase==2 & pData$Activity==3 & pData$Time < 250,]
  pData_seg3 <- pData[pData$Phase==3 & pData$Activity==3 & pData$Time < 350,]
  pData_seg4 <- pData[pData$Phase==4 & pData$Activity==3,]
  
  # pData_HighAcc <- pData[pData$Acceleration >= acc_thresholds[[p]],]
  # pData_LowAcc <- pData[pData$Acceleration < acc_thresholds[[p]],]
  pData_HighAcc <- pData[pData$Acc_std >= acc_sd_thresholds[[p]] | pData$Speed_std >= speed_sd_thresholds[[p]],]
  pData_LowAcc <- pData[pData$Acc_std < acc_sd_thresholds[[p]] & pData$Speed_std < speed_sd_thresholds[[p]],]
  
  pData_HighAcc1 <- pData_HighAcc[(pData_HighAcc$Distance < 350),]
  pData_LowAcc1 <- pData_LowAcc[(pData_LowAcc$Distance < 350),]
  pData_HighAcc2 <- pData_HighAcc[(pData_HighAcc$Distance >= 350 & pData_HighAcc$Distance < 700),]
  pData_LowAcc2 <- pData_LowAcc[(pData_LowAcc$Distance >= 350 & pData_LowAcc$Distance < 700),]
  pData_HighAcc3 <- pData_HighAcc[(pData_HighAcc$Distance >= 700 & pData_HighAcc$Distance < 1050),]
  pData_LowAcc3 <- pData_LowAcc[(pData_LowAcc$Distance >= 700 & pData_LowAcc$Distance < 1050),]
  pData_HighAcc4 <- pData_HighAcc[(pData_HighAcc$Distance >= 1050),]
  pData_LowAcc4 <- pData_LowAcc[(pData_LowAcc$Distance >= 1050),]
  
  mean_pp[[p]] <- mean(pData_act3$ppLogNormalized)
  std_pp[[p]] <- sd(pData$ppLogNormalized)
  
  mean_pp_seg0[[p]] <- mean(pData_seg0$ppLogNormalized)
  mean_pp_seg0_1[[p]] <- mean(pData_seg0_1$ppLogNormalized)
  mean_pp_seg0_2[[p]] <- mean(pData_seg0_2$ppLogNormalized)
  mean_pp_seg0_3[[p]] <- mean(pData_seg0_3$ppLogNormalized)
  mean_pp_seg0_4[[p]] <- mean(pData_seg0_4$ppLogNormalized)
  
  mean_pp_seg1[[p]] <- mean(pData_seg1$ppLogNormalized)
  mean_pp_seg2[[p]] <- mean(pData_seg2$ppLogNormalized)
  mean_pp_seg3[[p]] <- mean(pData_seg3$ppLogNormalized)
  mean_pp_seg4[[p]] <- mean(pData_seg4$ppLogNormalized)
  mean_pp_max[[p]] <- max(mean_pp_seg1[[p]], mean_pp_seg2[[p]], mean_pp_seg3[[p]], mean_pp_seg4[[p]])
  
  std_pp_seg0[[p]] <- sd(pData_seg0$ppLogNormalized)
  std_pp_seg0_1[[p]] <- sd(pData_seg0_1$ppLogNormalized)
  std_pp_seg0_2[[p]] <- sd(pData_seg0_2$ppLogNormalized)
  std_pp_seg0_3[[p]] <- sd(pData_seg0_3$ppLogNormalized)
  std_pp_seg0_4[[p]] <- sd(pData_seg0_4$ppLogNormalized)
  
  std_pp_seg1[[p]] <- sd(pData_seg1$ppLogNormalized)
  std_pp_seg2[[p]] <- sd(pData_seg2$ppLogNormalized)
  std_pp_seg3[[p]] <- sd(pData_seg3$ppLogNormalized)
  std_pp_seg4[[p]] <- sd(pData_seg4$ppLogNormalized)
  std_pp_max[[p]] <- max(std_pp_seg1[[p]], std_pp_seg2[[p]], std_pp_seg3[[p]], std_pp_seg4[[p]])
  
  # Acceleration
  mean_pp_HighAcc[[p]] <- mean(pData_HighAcc$ppNext)
  mean_pp_LowAcc[[p]] <- mean(pData_LowAcc$ppNext)
  std_pp_HighAcc[[p]] <- sd(pData_HighAcc$ppNext)
  std_pp_LowAcc[[p]] <- sd(pData_LowAcc$ppNext)
  
  mean_pp_HighAcc1[[p]] <- mean(pData_HighAcc1$ppNext)
  mean_pp_LowAcc1[[p]] <- mean(pData_LowAcc1$ppNext)
  std_pp_HighAcc1[[p]] <- sd(pData_HighAcc1$ppNext)
  std_pp_LowAcc1[[p]] <- sd(pData_LowAcc1$ppNext)
  
  mean_pp_HighAcc2[[p]] <- mean(pData_HighAcc2$ppNext)
  mean_pp_LowAcc2[[p]] <- mean(pData_LowAcc2$ppNext)
  std_pp_HighAcc2[[p]] <- sd(pData_HighAcc2$ppNext)
  std_pp_LowAcc2[[p]] <- sd(pData_LowAcc2$ppNext)
  
  mean_pp_HighAcc3[[p]] <- mean(pData_HighAcc3$ppNext)
  mean_pp_LowAcc3[[p]] <- mean(pData_LowAcc3$ppNext)
  std_pp_HighAcc3[[p]] <- sd(pData_HighAcc3$ppNext)
  std_pp_LowAcc3[[p]] <- sd(pData_LowAcc3$ppNext)
  
  mean_pp_HighAcc4[[p]] <- mean(pData_HighAcc4$ppNext)
  mean_pp_LowAcc4[[p]] <- mean(pData_LowAcc4$ppNext)
  std_pp_HighAcc4[[p]] <- sd(pData_HighAcc4$ppNext)
  std_pp_LowAcc4[[p]] <- sd(pData_LowAcc4$ppNext)
}
plt_AllAcc <- vector(mode="list", length=length(persons)) 
names(plt_AllAcc) <- persons

COLOR_ACC = "#02A3C8"
COLOR_PP = "#F28E8E"
COLOR_BRAKE = "#888888"

y1 <- list(
  tickfont = list(color = COLOR_ACC),
  title="Degree",
  range=c(0, max(all_Drive3$Acceleration))
)
y2 <- list(
  tickfont = list(color = COLOR_PP),
  overlaying = "y",
  side = "right",
  title = "Log Perspiration",
  showgrid = FALSE,
  range=c(-0.6, 0.9)
  # range=c(min(all_Drive3$ppLogNormalized), max(all_Drive3$ppLogNormalized))
)

for (p in persons) {
  pData <- all_Drive3[(all_Drive3$Subject==as.integer(p) | all_Drive3$Subject==p),]
  pData_seg0 <- pData[pData$Phase==0,]
  pData_seg1 <- pData[pData$Phase==1 & pData$Activity==3 & pData$Time < 110,]
  pData_seg2 <- pData[pData$Phase==2 & pData$Activity==3 & pData$Time < 250,]
  pData_seg3 <- pData[pData$Phase==3 & pData$Activity==3 & pData$Time < 350,]
  pData_seg4 <- pData[pData$Phase==4 & pData$Activity==3,]
  
  plot_Acc <- plot_ly(pData, x = ~Time, height=400, width=900) %>%
    # add_trace(name="Acceleration", y = ~Acceleration, type = 'scatter', mode = 'lines', line=list(width=1.5, color=COLOR_ACC)) %>% 
    add_trace(name="PP", y = ~ppLogNormalized, type = 'scatter', mode = 'lines', line=list(width=1.5, color=COLOR_PP), yaxis = "y2") %>%
    add_segments(x = min(pData$Time), xend = max(pData$Time), y = mean_pp[[p]], yend = mean_pp[[p]], 
                           yaxis = "y2", name="Avg. PP (straight)",
                           line=list(color="darkgray", dash = 'dot')) %>%
    add_segments(x = min(pData$Time), xend = max(pData$Time), y = mean_pp_seg0[[p]], yend = mean_pp_seg0[[p]], 
                           yaxis = "y2", name="Avg. PP (turning)",
                           line=list(color="black", dash = 'dot')) %>%
    add_segments(x = min(pData_seg1$Time), xend = max(pData_seg1$Time), y = mean_pp_seg1[[p]], yend = mean_pp_seg1[[p]], 
                           yaxis = "y2", name="Avg. PP (1st part)",
                           line=list(color="red", dash = 'dot')) %>%
    add_segments(x = min(pData_seg2$Time), xend = max(pData_seg2$Time), y = mean_pp_seg2[[p]], yend = mean_pp_seg2[[p]], 
                           yaxis = "y2", name="Avg. PP (2nd part)",
                           line=list(color="green", dash = 'dot')) %>%
    add_segments(x = min(pData_seg3$Time), xend = max(pData_seg3$Time), y = mean_pp_seg3[[p]], yend = mean_pp_seg3[[p]], 
                           yaxis = "y2", name="Avg. PP (3rd part)",
                           line=list(color="blue", dash = 'dot')) %>%
    add_segments(x = min(pData_seg4$Time), xend = max(pData_seg4$Time), y = mean_pp_seg4[[p]], yend = mean_pp_seg4[[p]], 
                           yaxis = "y2", name="Avg. PP (4th part)",
                           line=list(color="purple", dash = 'dot')) %>%
    layout(
      title=paste0("Subject #", p), 
      xaxis=list(title="Time [s]", range=c(0)), 
      yaxis=y1, 
      yaxis2=y2, 
      margin = list(l = 50, r = 50, b = 50, t = 50, pad = 4),
      legend = list(x = 0.5, xanchor = "center", y = 0.2, bgcolor = "rgba(0,0,0,0)", title="Metric", orientation = "h"),
      autosize = F
    )
  
  plt_AllAcc[[p]] <- plot_Acc
}


htmltools::tagList(plt_AllAcc)
NUMBER_OF_CLUSTERS = 3

color_darkpink = "#e75480"
CLUSTER_BRANCH_COLORS <- c("blue", "darkred", color_darkpink, "black")[1:NUMBER_OF_CLUSTERS]
CLUSTER_LABEL_COLORS <- c("blue", "darkred", color_darkpink, "black")[1:NUMBER_OF_CLUSTERS]

dfPP <- as.data.frame(cbind(
                            unlist(mean_pp), 
                            unlist(std_pp), 
                            unlist(mean_pp_seg0), 
                            unlist(mean_pp_seg1), 
                            unlist(mean_pp_seg2), 
                            unlist(mean_pp_seg3), 
                            unlist(mean_pp_seg4),
                            unlist(mean_pp_max),
                            unlist(std_pp_seg0), 
                            unlist(std_pp_seg1), 
                            unlist(std_pp_seg2), 
                            unlist(std_pp_seg3), 
                            unlist(std_pp_seg4),
                            unlist(std_pp_max),
                            unlist(mean_pp_seg0_1),
                            unlist(mean_pp_seg0_2),
                            unlist(mean_pp_seg0_3),
                            unlist(mean_pp_seg0_4),
                            unlist(std_pp_seg0_1),
                            unlist(std_pp_seg0_2),
                            unlist(std_pp_seg0_3),
                            unlist(std_pp_seg0_4),
                            unlist(mean_pp_HighAcc),
                            unlist(mean_pp_LowAcc),
                            unlist(std_pp_HighAcc),
                            unlist(std_pp_LowAcc),
                            unlist(mean_pp_HighAcc1),
                            unlist(mean_pp_LowAcc1),
                            unlist(std_pp_HighAcc1),
                            unlist(std_pp_LowAcc1),
                            unlist(mean_pp_HighAcc2),
                            unlist(mean_pp_LowAcc2),
                            unlist(std_pp_HighAcc2),
                            unlist(std_pp_LowAcc2),
                            unlist(mean_pp_HighAcc3),
                            unlist(mean_pp_LowAcc3),
                            unlist(std_pp_HighAcc3),
                            unlist(std_pp_LowAcc3),
                            unlist(mean_pp_HighAcc4),
                            unlist(mean_pp_LowAcc4),
                            unlist(std_pp_HighAcc4),
                            unlist(std_pp_LowAcc4)
                    ))

names(dfPP) <- c("MeanPP", "StdPP", 
                 "MeanPP_Seg0", "MeanPP_Seg1", "MeanPP_Seg2", "MeanPP_Seg3", "MeanPP_Seg4", "MeanPP_SegMax",
                 "StdPP_Seg0", "StdPP_Seg1", "StdPP_Seg2", "StdPP_Seg3", "StdPP_Seg4", "StdPP_SegMax",
                 "MeanPP_Seg0_1", "MeanPP_Seg0_2", "MeanPP_Seg0_3", "MeanPP_Seg0_4",
                 "StdPP_Seg0_1", "StdPP_Seg0_2", "StdPP_Seg0_3", "StdPP_Seg0_4",
                 "MeanPP_AccHigh", " MeanPP_AccLow", "StdPP_AccHigh", "StdPP_AccLow",
                 "MeanPP_AccHigh1", " MeanPP_AccLow1", "StdPP_AccHigh1", "StdPP_AccLow1",
                 "MeanPP_AccHigh2", " MeanPP_AccLow2", "StdPP_AccHigh2", "StdPP_AccLow2",
                 "MeanPP_AccHigh3", " MeanPP_AccLow3", "StdPP_AccHigh3", "StdPP_AccLow3",
                 "MeanPP_AccHigh4", " MeanPP_AccLow4", "StdPP_AccHigh4", "StdPP_AccLow4")

behavioralMatrixClustering <- as.matrix(dfPP)

distMatrix <- dist(behavioralMatrixClustering)
hresults <- distMatrix %>% hclust(method="average")

hc <- hresults %>% 
      as.dendrogram %>%
      set("nodes_cex", NUMBER_OF_CLUSTERS) %>%
      set("labels_col", value = CLUSTER_LABEL_COLORS, k=NUMBER_OF_CLUSTERS) %>%
      # set("leaves_pch", 19) %>%
      # set("leaves_col", value = c("gray"), k=NUMBER_OF_CLUSTERS) %>%    
      set("branches_k_color", value=CLUSTER_BRANCH_COLORS, k=NUMBER_OF_CLUSTERS)

plot(hc)
legend("topright", 
     title="Drive=Motoric \nHierachical Clustering",
     legend = c("Group 1", "Group 2", "Group 3"), 
     col = c("darkred", "pink" , "blue"),
     pch = c(20,20,20), bty = "n",  pt.cex = 1.5, cex = 0.8 , 
     text.col = "black", horiz = FALSE, inset = c(0.4, 0.1))

Clustering with SD of PP

library(dendextend)

clusteringDf <- dfPP %>% select(StdPP)
NUMBER_OF_CLUSTERS = 3

color_darkpink = "#e75480"
CLUSTER_BRANCH_COLORS <- c("darkred", "blue", "red")[1:NUMBER_OF_CLUSTERS]
CLUSTER_LABEL_COLORS <- c("darkred", "blue", "red")[1:NUMBER_OF_CLUSTERS]

behavioralMatrixClustering <- as.matrix(clusteringDf)
rownames(behavioralMatrixClustering) <- paste0("#", persons)
distMatrix <- dist(behavioralMatrixClustering)
hresults <- distMatrix %>% hclust

hc <- hresults %>% 
      as.dendrogram %>%
      set("nodes_cex", NUMBER_OF_CLUSTERS) %>%
      set("labels_col", value = CLUSTER_LABEL_COLORS, k=NUMBER_OF_CLUSTERS) %>%
      # set("leaves_pch", 19) %>%
      # set("leaves_col", value = c("gray"), k=NUMBER_OF_CLUSTERS) %>%    
      set("branches_k_color", value=CLUSTER_BRANCH_COLORS, k=NUMBER_OF_CLUSTERS)

plot(hc)
legend("topright", 
     title="Drive=Motoric \nChange of Arousal",
     legend = c("Exceptional SD" , "Low SD" , "High SD"), 
     col = c("darkred", "blue" , "red"),
     pch = c(20,20,20), bty = "n",  pt.cex = 1.5, cex = 0.8 , 
     text.col = "black", horiz = FALSE, inset = c(0.0, 0.1))

library(cluster)
silhouette_score <- function(k){
  km <- kmeans(clusteringDf, centers = k, nstart=25)
  ss <- silhouette(km$cluster, dist(clusteringDf))
  mean(ss[, 3])
}
k <- 2:10
avg_sil <- sapply(k, silhouette_score)
plot(k, type='b', avg_sil, xlab='Number of clusters', ylab='Average Silhouette Scores', frame=FALSE)

# Store clustering data
fPath <- str_interp("../data/processed/analysis/TT1_Drive_3_PP.csv")
dfx <- dfPP
dfx <- cbind(persons, dfx)
names(dfx) <- c("Subject" , names(dfPP))
write.csv(dfx, fPath, row.names = F)
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CnNvdXJjZSgnLi4vc2V0dGluZ3Mvc2V0dGluZ3MuUicpCnNvdXJjZSgnY29tbW9uRnVuY3Rpb25zLlInKQpgYGAKCmBgYHtyfQpwZXJzb25zIDwtIFNFTEVDVEVEX1NVQkpFQ1RTCgphbGxfRHJpdmUzIDwtIHJlYWQuY3N2KCcuLi8vZGF0YS9wcm9jZXNzZWQvZGlzdGFuY2V3aXNlL1RUMV9Ecml2ZV8zXzE1bV8xNW0uY3N2JykKYWxsX0RyaXZlMyRTdWJqZWN0IDwtIGFzLmZhY3RvcihhbGxfRHJpdmUzJFN1YmplY3QpCmFsbF9Ecml2ZTMkbG9nUGVyc3BpcmF0aW9uIDwtIGxvZyhhbGxfRHJpdmUzJFBlcnNwaXJhdGlvbikKYGBgCgojIEFjY2VsZXJhdGlvbiBQbG90CmBgYHtyfQpjb21wdXRlVGhyZXNob2xkIDwtIGZ1bmN0aW9uKHgsIHhtaW49bWluKHgpLCB4bWF4PW1heCh4KSkgewogIHggPC0geFt4ID49IHhtaW4gJiB4IDw9IHhtYXhdCiAgeEFyciA8LSBtYXRyaXgoeCwgbnJvdyA9IDEsIG5jb2wgPSBsZW5ndGgoeCkpCiAgdGhyZXNob2xkIDwtIG90c3UoeEFyciwgcmFuZ2U9Yyh4bWluLCB4bWF4KSkKICByZXR1cm4odGhyZXNob2xkKQp9CmNvbXB1dGVUaHJlc2hvbGRGb3JBY2NlbGVyYXRpb24gPC0gZnVuY3Rpb24oYWNjKXsKICByZXR1cm4oY29tcHV0ZVRocmVzaG9sZChhY2MsIHhtaW49MCwgeG1heD0yMCkpCn0KZmluZE1vZGVzIDwtIGZ1bmN0aW9uKHgpIHsKICB1eCA8LSB1bmlxdWUoeCkKICB1eFt3aGljaC5tYXgodGFidWxhdGUobWF0Y2goeCwgdXgpKSldCn0KYGBgCgpgYGB7cn0KYWNjX3RocmVzaG9sZHMgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoYWNjX3RocmVzaG9sZHMpIDwtIHBlcnNvbnMKCmFjY19zZF90aHJlc2hvbGRzIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKGFjY19zZF90aHJlc2hvbGRzKSA8LSBwZXJzb25zCgpzcGVlZF9zZF90aHJlc2hvbGRzIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHNwZWVkX3NkX3RocmVzaG9sZHMpIDwtIHBlcnNvbnMKCmZvciAocCBpbiBwZXJzb25zKSB7CiAgcERhdGEgPC0gYWxsX0RyaXZlM1soYWxsX0RyaXZlMyRTdWJqZWN0PT1hcy5pbnRlZ2VyKHApIHwgYWxsX0RyaXZlMyRTdWJqZWN0PT1wKSxdCiAgYWNjX3RoIDwtIGNvbXB1dGVUaHJlc2hvbGRGb3JBY2NlbGVyYXRpb24ocERhdGEkQWNjZWxlcmF0aW9uKQogIGFjY190aF9zZCA8LSBjb21wdXRlVGhyZXNob2xkRm9yQWNjZWxlcmF0aW9uKHBEYXRhJEFjY19zdGQpCiAgc3BlZWRfdGhfc2QgPC0gY29tcHV0ZVRocmVzaG9sZEZvckFjY2VsZXJhdGlvbihwRGF0YSRTcGVlZF9zdGQpCiAgYWNjX3RocmVzaG9sZHNbW3BdXSA8LSBhcy5udW1lcmljKGFjY190aCkKICBhY2Nfc2RfdGhyZXNob2xkc1tbcF1dIDwtIGFzLm51bWVyaWMoYWNjX3RoX3NkKQogIHNwZWVkX3NkX3RocmVzaG9sZHNbW3BdXSA8LSBhcy5udW1lcmljKHNwZWVkX3RoX3NkKQogIAogIGFjY19wbCA8LSBnZ3Bsb3QocERhdGEsIGFlcyh4PUFjY2VsZXJhdGlvbikpICsgZ2VvbV9kZW5zaXR5KCkgKyBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0PWFjY190aCksIGNvbG9yPSJibHVlIiwgbGluZXR5cGU9ImRhc2hlZCIsIHNpemU9MSkKICBhY2Nfc2RfcGwgPC0gZ2dwbG90KHBEYXRhLCBhZXMoeD1BY2Nfc3RkKSkgKyBnZW9tX2RlbnNpdHkoKSArIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQ9YWNjX3RoX3NkKSwgY29sb3I9InJlZCIsIGxpbmV0eXBlPSJkYXNoZWQiLCBzaXplPTEpCiAgc3BlZWRfc2RfcGwgPC0gZ2dwbG90KHBEYXRhLCBhZXMoeD1TcGVlZF9zdGQpKSArIGdlb21fZGVuc2l0eSgpICsgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD1zcGVlZF90aF9zZCksIGNvbG9yPSJyZWQiLCBsaW5ldHlwZT0iZGFzaGVkIiwgc2l6ZT0xKQogIAogIHBsb3Qoc3BlZWRfc2RfcGwpCiAgcHJpbnQocGFzdGUwKHAsICIgLSBUaHJlc2hvbGQgKEFjYykgPSIsIGFjY190aCwgIiAmIChBY2MgU0QpID0iLCBhY2NfdGhfc2QsICIgJiAoU3BlZWQgU0QpID0iLCBhY2NfdGhfc2QpKQogIAp9CmBgYAoKYGBge3J9Cm1lYW5fcHAgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcCkgPC0gcGVyc29ucwoKc3RkX3BwIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcCkgPC0gcGVyc29ucwoKIyBNZWFuIChUdXJuaW5nKQptZWFuX3BwX3NlZzAgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9zZWcwKSA8LSBwZXJzb25zCm1lYW5fcHBfc2VnMF8xIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfc2VnMF8xKSA8LSBwZXJzb25zCm1lYW5fcHBfc2VnMF8yIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfc2VnMF8yKSA8LSBwZXJzb25zCm1lYW5fcHBfc2VnMF8zIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfc2VnMF8zKSA8LSBwZXJzb25zCm1lYW5fcHBfc2VnMF80IDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfc2VnMF80KSA8LSBwZXJzb25zCgojIE1lYW4gKFN0cmFpZ2h0KQptZWFuX3BwX3NlZzEgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9zZWcxKSA8LSBwZXJzb25zCm1lYW5fcHBfc2VnMiA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX3NlZzIpIDwtIHBlcnNvbnMKbWVhbl9wcF9zZWczIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfc2VnMykgPC0gcGVyc29ucwptZWFuX3BwX3NlZzQgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9zZWc0KSA8LSBwZXJzb25zCm1lYW5fcHBfbWF4IDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfbWF4KSA8LSBwZXJzb25zCgojIFNEIChUdXJuaW5nKQpzdGRfcHBfc2VnMCA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfc2VnMCkgPC0gcGVyc29ucwpzdGRfcHBfc2VnMF8xIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9zZWcwXzEpIDwtIHBlcnNvbnMKc3RkX3BwX3NlZzBfMiA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfc2VnMF8yKSA8LSBwZXJzb25zCnN0ZF9wcF9zZWcwXzMgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMoc3RkX3BwX3NlZzBfMykgPC0gcGVyc29ucwpzdGRfcHBfc2VnMF80IDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9zZWcwXzQpIDwtIHBlcnNvbnMKCiMgU0QgKFN0cmFpZ2h0KQpzdGRfcHBfc2VnMSA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfc2VnMSkgPC0gcGVyc29ucwpzdGRfcHBfc2VnMiA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfc2VnMikgPC0gcGVyc29ucwpzdGRfcHBfc2VnMyA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfc2VnMykgPC0gcGVyc29ucwpzdGRfcHBfc2VnNCA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfc2VnNCkgPC0gcGVyc29ucwpzdGRfcHBfbWF4IDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9tYXgpIDwtIHBlcnNvbnMKCiMgQWNjZWxlcmF0aW9uIFBhcnRpdGlvbmluZwptZWFuX3BwX0hpZ2hBY2MgPC0gdmVjdG9yKG1vZGU9Imxpc3QiLCBsZW5ndGg9bGVuZ3RoKHBlcnNvbnMpKSAKbmFtZXMobWVhbl9wcF9IaWdoQWNjKSA8LSBwZXJzb25zCm1lYW5fcHBfTG93QWNjIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKG1lYW5fcHBfTG93QWNjKSA8LSBwZXJzb25zCgpzdGRfcHBfSGlnaEFjYyA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfSGlnaEFjYykgPC0gcGVyc29ucwpzdGRfcHBfTG93QWNjIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9Mb3dBY2MpIDwtIHBlcnNvbnMKCiMgQWNjZWwgKyBTZWdtZW50YXRpb24KbWVhbl9wcF9IaWdoQWNjMSA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX0hpZ2hBY2MxKSA8LSBwZXJzb25zCm1lYW5fcHBfTG93QWNjMSA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX0xvd0FjYzEpIDwtIHBlcnNvbnMKc3RkX3BwX0hpZ2hBY2MxIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9IaWdoQWNjMSkgPC0gcGVyc29ucwpzdGRfcHBfTG93QWNjMSA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfTG93QWNjMSkgPC0gcGVyc29ucwoKbWVhbl9wcF9IaWdoQWNjMiA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX0hpZ2hBY2MyKSA8LSBwZXJzb25zCm1lYW5fcHBfTG93QWNjMiA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX0xvd0FjYzIpIDwtIHBlcnNvbnMKc3RkX3BwX0hpZ2hBY2MyIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9IaWdoQWNjMikgPC0gcGVyc29ucwpzdGRfcHBfTG93QWNjMiA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfTG93QWNjMikgPC0gcGVyc29ucwoKbWVhbl9wcF9IaWdoQWNjMyA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX0hpZ2hBY2MzKSA8LSBwZXJzb25zCm1lYW5fcHBfTG93QWNjMyA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX0xvd0FjYzMpIDwtIHBlcnNvbnMKc3RkX3BwX0hpZ2hBY2MzIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9IaWdoQWNjMykgPC0gcGVyc29ucwpzdGRfcHBfTG93QWNjMyA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfTG93QWNjMykgPC0gcGVyc29ucwoKbWVhbl9wcF9IaWdoQWNjNCA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX0hpZ2hBY2M0KSA8LSBwZXJzb25zCm1lYW5fcHBfTG93QWNjNCA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhtZWFuX3BwX0xvd0FjYzQpIDwtIHBlcnNvbnMKc3RkX3BwX0hpZ2hBY2M0IDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHN0ZF9wcF9IaWdoQWNjNCkgPC0gcGVyc29ucwpzdGRfcHBfTG93QWNjNCA8LSB2ZWN0b3IobW9kZT0ibGlzdCIsIGxlbmd0aD1sZW5ndGgocGVyc29ucykpIApuYW1lcyhzdGRfcHBfTG93QWNjNCkgPC0gcGVyc29ucwoKZm9yKHAgaW4gcGVyc29ucykgewogIHBEYXRhIDwtIGFsbF9Ecml2ZTNbKGFsbF9Ecml2ZTMkU3ViamVjdD09YXMuaW50ZWdlcihwKSB8IGFsbF9Ecml2ZTMkU3ViamVjdD09cCksXQogIHBEYXRhX2FjdDMgPC0gcERhdGFbcERhdGEkQWN0aXZpdHk9PTMsXQogIAogICMgRGF0YSBQYXJ0aXRpb25pbmcKICBwRGF0YV9zZWcwIDwtIHBEYXRhW3BEYXRhJFBoYXNlPT0wLF0KICBwRGF0YV9zZWcwXzEgPC0gcERhdGFbcERhdGEkQWN0aXZpdHk9PTAgJiBwRGF0YSRQaGFzZT09MCAmIHBEYXRhJFRpbWUgPiAxMDAgJiBwRGF0YSRUaW1lIDwgMjAwLF0KICBwRGF0YV9zZWcwXzIgPC0gcERhdGFbcERhdGEkQWN0aXZpdHk9PTAgJiBwRGF0YSRQaGFzZT09MCAmIHBEYXRhJFRpbWUgPiAyMDAgJiBwRGF0YSRUaW1lIDwgMzAwLF0KICBwRGF0YV9zZWcwXzMgPC0gcERhdGFbcERhdGEkQWN0aXZpdHk9PTAgJiBwRGF0YSRQaGFzZT09MCAmIHBEYXRhJFRpbWUgPiAzMDAgJiBwRGF0YSRUaW1lIDwgNDAwLF0KICBwRGF0YV9zZWcwXzQgPC0gcERhdGFbcERhdGEkQWN0aXZpdHk9PTAgJiBwRGF0YSRQaGFzZT09MCAmIHBEYXRhJFRpbWUgPiA0MDAgJiBwRGF0YSRUaW1lIDwgNTAwLF0KICAKICBwRGF0YV9zZWcxIDwtIHBEYXRhW3BEYXRhJFBoYXNlPT0xICYgcERhdGEkQWN0aXZpdHk9PTMgJiBwRGF0YSRUaW1lIDwgMTEwLF0KICBwRGF0YV9zZWcyIDwtIHBEYXRhW3BEYXRhJFBoYXNlPT0yICYgcERhdGEkQWN0aXZpdHk9PTMgJiBwRGF0YSRUaW1lIDwgMjUwLF0KICBwRGF0YV9zZWczIDwtIHBEYXRhW3BEYXRhJFBoYXNlPT0zICYgcERhdGEkQWN0aXZpdHk9PTMgJiBwRGF0YSRUaW1lIDwgMzUwLF0KICBwRGF0YV9zZWc0IDwtIHBEYXRhW3BEYXRhJFBoYXNlPT00ICYgcERhdGEkQWN0aXZpdHk9PTMsXQogIAogICMgcERhdGFfSGlnaEFjYyA8LSBwRGF0YVtwRGF0YSRBY2NlbGVyYXRpb24gPj0gYWNjX3RocmVzaG9sZHNbW3BdXSxdCiAgIyBwRGF0YV9Mb3dBY2MgPC0gcERhdGFbcERhdGEkQWNjZWxlcmF0aW9uIDwgYWNjX3RocmVzaG9sZHNbW3BdXSxdCiAgcERhdGFfSGlnaEFjYyA8LSBwRGF0YVtwRGF0YSRBY2Nfc3RkID49IGFjY19zZF90aHJlc2hvbGRzW1twXV0gfCBwRGF0YSRTcGVlZF9zdGQgPj0gc3BlZWRfc2RfdGhyZXNob2xkc1tbcF1dLF0KICBwRGF0YV9Mb3dBY2MgPC0gcERhdGFbcERhdGEkQWNjX3N0ZCA8IGFjY19zZF90aHJlc2hvbGRzW1twXV0gJiBwRGF0YSRTcGVlZF9zdGQgPCBzcGVlZF9zZF90aHJlc2hvbGRzW1twXV0sXQogIAogIHBEYXRhX0hpZ2hBY2MxIDwtIHBEYXRhX0hpZ2hBY2NbKHBEYXRhX0hpZ2hBY2MkRGlzdGFuY2UgPCAzNTApLF0KICBwRGF0YV9Mb3dBY2MxIDwtIHBEYXRhX0xvd0FjY1socERhdGFfTG93QWNjJERpc3RhbmNlIDwgMzUwKSxdCiAgcERhdGFfSGlnaEFjYzIgPC0gcERhdGFfSGlnaEFjY1socERhdGFfSGlnaEFjYyREaXN0YW5jZSA+PSAzNTAgJiBwRGF0YV9IaWdoQWNjJERpc3RhbmNlIDwgNzAwKSxdCiAgcERhdGFfTG93QWNjMiA8LSBwRGF0YV9Mb3dBY2NbKHBEYXRhX0xvd0FjYyREaXN0YW5jZSA+PSAzNTAgJiBwRGF0YV9Mb3dBY2MkRGlzdGFuY2UgPCA3MDApLF0KICBwRGF0YV9IaWdoQWNjMyA8LSBwRGF0YV9IaWdoQWNjWyhwRGF0YV9IaWdoQWNjJERpc3RhbmNlID49IDcwMCAmIHBEYXRhX0hpZ2hBY2MkRGlzdGFuY2UgPCAxMDUwKSxdCiAgcERhdGFfTG93QWNjMyA8LSBwRGF0YV9Mb3dBY2NbKHBEYXRhX0xvd0FjYyREaXN0YW5jZSA+PSA3MDAgJiBwRGF0YV9Mb3dBY2MkRGlzdGFuY2UgPCAxMDUwKSxdCiAgcERhdGFfSGlnaEFjYzQgPC0gcERhdGFfSGlnaEFjY1socERhdGFfSGlnaEFjYyREaXN0YW5jZSA+PSAxMDUwKSxdCiAgcERhdGFfTG93QWNjNCA8LSBwRGF0YV9Mb3dBY2NbKHBEYXRhX0xvd0FjYyREaXN0YW5jZSA+PSAxMDUwKSxdCiAgCiAgbWVhbl9wcFtbcF1dIDwtIG1lYW4ocERhdGFfYWN0MyRwcExvZ05vcm1hbGl6ZWQpCiAgc3RkX3BwW1twXV0gPC0gc2QocERhdGEkcHBMb2dOb3JtYWxpemVkKQogIAogIG1lYW5fcHBfc2VnMFtbcF1dIDwtIG1lYW4ocERhdGFfc2VnMCRwcExvZ05vcm1hbGl6ZWQpCiAgbWVhbl9wcF9zZWcwXzFbW3BdXSA8LSBtZWFuKHBEYXRhX3NlZzBfMSRwcExvZ05vcm1hbGl6ZWQpCiAgbWVhbl9wcF9zZWcwXzJbW3BdXSA8LSBtZWFuKHBEYXRhX3NlZzBfMiRwcExvZ05vcm1hbGl6ZWQpCiAgbWVhbl9wcF9zZWcwXzNbW3BdXSA8LSBtZWFuKHBEYXRhX3NlZzBfMyRwcExvZ05vcm1hbGl6ZWQpCiAgbWVhbl9wcF9zZWcwXzRbW3BdXSA8LSBtZWFuKHBEYXRhX3NlZzBfNCRwcExvZ05vcm1hbGl6ZWQpCiAgCiAgbWVhbl9wcF9zZWcxW1twXV0gPC0gbWVhbihwRGF0YV9zZWcxJHBwTG9nTm9ybWFsaXplZCkKICBtZWFuX3BwX3NlZzJbW3BdXSA8LSBtZWFuKHBEYXRhX3NlZzIkcHBMb2dOb3JtYWxpemVkKQogIG1lYW5fcHBfc2VnM1tbcF1dIDwtIG1lYW4ocERhdGFfc2VnMyRwcExvZ05vcm1hbGl6ZWQpCiAgbWVhbl9wcF9zZWc0W1twXV0gPC0gbWVhbihwRGF0YV9zZWc0JHBwTG9nTm9ybWFsaXplZCkKICBtZWFuX3BwX21heFtbcF1dIDwtIG1heChtZWFuX3BwX3NlZzFbW3BdXSwgbWVhbl9wcF9zZWcyW1twXV0sIG1lYW5fcHBfc2VnM1tbcF1dLCBtZWFuX3BwX3NlZzRbW3BdXSkKICAKICBzdGRfcHBfc2VnMFtbcF1dIDwtIHNkKHBEYXRhX3NlZzAkcHBMb2dOb3JtYWxpemVkKQogIHN0ZF9wcF9zZWcwXzFbW3BdXSA8LSBzZChwRGF0YV9zZWcwXzEkcHBMb2dOb3JtYWxpemVkKQogIHN0ZF9wcF9zZWcwXzJbW3BdXSA8LSBzZChwRGF0YV9zZWcwXzIkcHBMb2dOb3JtYWxpemVkKQogIHN0ZF9wcF9zZWcwXzNbW3BdXSA8LSBzZChwRGF0YV9zZWcwXzMkcHBMb2dOb3JtYWxpemVkKQogIHN0ZF9wcF9zZWcwXzRbW3BdXSA8LSBzZChwRGF0YV9zZWcwXzQkcHBMb2dOb3JtYWxpemVkKQogIAogIHN0ZF9wcF9zZWcxW1twXV0gPC0gc2QocERhdGFfc2VnMSRwcExvZ05vcm1hbGl6ZWQpCiAgc3RkX3BwX3NlZzJbW3BdXSA8LSBzZChwRGF0YV9zZWcyJHBwTG9nTm9ybWFsaXplZCkKICBzdGRfcHBfc2VnM1tbcF1dIDwtIHNkKHBEYXRhX3NlZzMkcHBMb2dOb3JtYWxpemVkKQogIHN0ZF9wcF9zZWc0W1twXV0gPC0gc2QocERhdGFfc2VnNCRwcExvZ05vcm1hbGl6ZWQpCiAgc3RkX3BwX21heFtbcF1dIDwtIG1heChzdGRfcHBfc2VnMVtbcF1dLCBzdGRfcHBfc2VnMltbcF1dLCBzdGRfcHBfc2VnM1tbcF1dLCBzdGRfcHBfc2VnNFtbcF1dKQogIAogICMgQWNjZWxlcmF0aW9uCiAgbWVhbl9wcF9IaWdoQWNjW1twXV0gPC0gbWVhbihwRGF0YV9IaWdoQWNjJHBwTmV4dCkKICBtZWFuX3BwX0xvd0FjY1tbcF1dIDwtIG1lYW4ocERhdGFfTG93QWNjJHBwTmV4dCkKICBzdGRfcHBfSGlnaEFjY1tbcF1dIDwtIHNkKHBEYXRhX0hpZ2hBY2MkcHBOZXh0KQogIHN0ZF9wcF9Mb3dBY2NbW3BdXSA8LSBzZChwRGF0YV9Mb3dBY2MkcHBOZXh0KQogIAogIG1lYW5fcHBfSGlnaEFjYzFbW3BdXSA8LSBtZWFuKHBEYXRhX0hpZ2hBY2MxJHBwTmV4dCkKICBtZWFuX3BwX0xvd0FjYzFbW3BdXSA8LSBtZWFuKHBEYXRhX0xvd0FjYzEkcHBOZXh0KQogIHN0ZF9wcF9IaWdoQWNjMVtbcF1dIDwtIHNkKHBEYXRhX0hpZ2hBY2MxJHBwTmV4dCkKICBzdGRfcHBfTG93QWNjMVtbcF1dIDwtIHNkKHBEYXRhX0xvd0FjYzEkcHBOZXh0KQogIAogIG1lYW5fcHBfSGlnaEFjYzJbW3BdXSA8LSBtZWFuKHBEYXRhX0hpZ2hBY2MyJHBwTmV4dCkKICBtZWFuX3BwX0xvd0FjYzJbW3BdXSA8LSBtZWFuKHBEYXRhX0xvd0FjYzIkcHBOZXh0KQogIHN0ZF9wcF9IaWdoQWNjMltbcF1dIDwtIHNkKHBEYXRhX0hpZ2hBY2MyJHBwTmV4dCkKICBzdGRfcHBfTG93QWNjMltbcF1dIDwtIHNkKHBEYXRhX0xvd0FjYzIkcHBOZXh0KQogIAogIG1lYW5fcHBfSGlnaEFjYzNbW3BdXSA8LSBtZWFuKHBEYXRhX0hpZ2hBY2MzJHBwTmV4dCkKICBtZWFuX3BwX0xvd0FjYzNbW3BdXSA8LSBtZWFuKHBEYXRhX0xvd0FjYzMkcHBOZXh0KQogIHN0ZF9wcF9IaWdoQWNjM1tbcF1dIDwtIHNkKHBEYXRhX0hpZ2hBY2MzJHBwTmV4dCkKICBzdGRfcHBfTG93QWNjM1tbcF1dIDwtIHNkKHBEYXRhX0xvd0FjYzMkcHBOZXh0KQogIAogIG1lYW5fcHBfSGlnaEFjYzRbW3BdXSA8LSBtZWFuKHBEYXRhX0hpZ2hBY2M0JHBwTmV4dCkKICBtZWFuX3BwX0xvd0FjYzRbW3BdXSA8LSBtZWFuKHBEYXRhX0xvd0FjYzQkcHBOZXh0KQogIHN0ZF9wcF9IaWdoQWNjNFtbcF1dIDwtIHNkKHBEYXRhX0hpZ2hBY2M0JHBwTmV4dCkKICBzdGRfcHBfTG93QWNjNFtbcF1dIDwtIHNkKHBEYXRhX0xvd0FjYzQkcHBOZXh0KQp9CgpgYGAKCmBgYHtyfQpwbHRfQWxsQWNjIDwtIHZlY3Rvcihtb2RlPSJsaXN0IiwgbGVuZ3RoPWxlbmd0aChwZXJzb25zKSkgCm5hbWVzKHBsdF9BbGxBY2MpIDwtIHBlcnNvbnMKCkNPTE9SX0FDQyA9ICIjMDJBM0M4IgpDT0xPUl9QUCA9ICIjRjI4RThFIgpDT0xPUl9CUkFLRSA9ICIjODg4ODg4IgoKeTEgPC0gbGlzdCgKICB0aWNrZm9udCA9IGxpc3QoY29sb3IgPSBDT0xPUl9BQ0MpLAogIHRpdGxlPSJEZWdyZWUiLAogIHJhbmdlPWMoMCwgbWF4KGFsbF9Ecml2ZTMkQWNjZWxlcmF0aW9uKSkKKQp5MiA8LSBsaXN0KAogIHRpY2tmb250ID0gbGlzdChjb2xvciA9IENPTE9SX1BQKSwKICBvdmVybGF5aW5nID0gInkiLAogIHNpZGUgPSAicmlnaHQiLAogIHRpdGxlID0gIkxvZyBQZXJzcGlyYXRpb24iLAogIHNob3dncmlkID0gRkFMU0UsCiAgcmFuZ2U9YygtMC42LCAwLjkpCiAgIyByYW5nZT1jKG1pbihhbGxfRHJpdmUzJHBwTG9nTm9ybWFsaXplZCksIG1heChhbGxfRHJpdmUzJHBwTG9nTm9ybWFsaXplZCkpCikKCmZvciAocCBpbiBwZXJzb25zKSB7CiAgcERhdGEgPC0gYWxsX0RyaXZlM1soYWxsX0RyaXZlMyRTdWJqZWN0PT1hcy5pbnRlZ2VyKHApIHwgYWxsX0RyaXZlMyRTdWJqZWN0PT1wKSxdCiAgcERhdGFfc2VnMCA8LSBwRGF0YVtwRGF0YSRQaGFzZT09MCxdCiAgcERhdGFfc2VnMSA8LSBwRGF0YVtwRGF0YSRQaGFzZT09MSAmIHBEYXRhJEFjdGl2aXR5PT0zICYgcERhdGEkVGltZSA8IDExMCxdCiAgcERhdGFfc2VnMiA8LSBwRGF0YVtwRGF0YSRQaGFzZT09MiAmIHBEYXRhJEFjdGl2aXR5PT0zICYgcERhdGEkVGltZSA8IDI1MCxdCiAgcERhdGFfc2VnMyA8LSBwRGF0YVtwRGF0YSRQaGFzZT09MyAmIHBEYXRhJEFjdGl2aXR5PT0zICYgcERhdGEkVGltZSA8IDM1MCxdCiAgcERhdGFfc2VnNCA8LSBwRGF0YVtwRGF0YSRQaGFzZT09NCAmIHBEYXRhJEFjdGl2aXR5PT0zLF0KICAKICBwbG90X0FjYyA8LSBwbG90X2x5KHBEYXRhLCB4ID0gflRpbWUsIGhlaWdodD00MDAsIHdpZHRoPTkwMCkgJT4lCiAgICAjIGFkZF90cmFjZShuYW1lPSJBY2NlbGVyYXRpb24iLCB5ID0gfkFjY2VsZXJhdGlvbiwgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdsaW5lcycsIGxpbmU9bGlzdCh3aWR0aD0xLjUsIGNvbG9yPUNPTE9SX0FDQykpICU+JSAKICAgIGFkZF90cmFjZShuYW1lPSJQUCIsIHkgPSB+cHBMb2dOb3JtYWxpemVkLCB0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ2xpbmVzJywgbGluZT1saXN0KHdpZHRoPTEuNSwgY29sb3I9Q09MT1JfUFApLCB5YXhpcyA9ICJ5MiIpICU+JQogICAgYWRkX3NlZ21lbnRzKHggPSBtaW4ocERhdGEkVGltZSksIHhlbmQgPSBtYXgocERhdGEkVGltZSksIHkgPSBtZWFuX3BwW1twXV0sIHllbmQgPSBtZWFuX3BwW1twXV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICB5YXhpcyA9ICJ5MiIsIG5hbWU9IkF2Zy4gUFAgKHN0cmFpZ2h0KSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmU9bGlzdChjb2xvcj0iZGFya2dyYXkiLCBkYXNoID0gJ2RvdCcpKSAlPiUKICAgIGFkZF9zZWdtZW50cyh4ID0gbWluKHBEYXRhJFRpbWUpLCB4ZW5kID0gbWF4KHBEYXRhJFRpbWUpLCB5ID0gbWVhbl9wcF9zZWcwW1twXV0sIHllbmQgPSBtZWFuX3BwX3NlZzBbW3BdXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHlheGlzID0gInkyIiwgbmFtZT0iQXZnLiBQUCAodHVybmluZykiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lPWxpc3QoY29sb3I9ImJsYWNrIiwgZGFzaCA9ICdkb3QnKSkgJT4lCiAgICBhZGRfc2VnbWVudHMoeCA9IG1pbihwRGF0YV9zZWcxJFRpbWUpLCB4ZW5kID0gbWF4KHBEYXRhX3NlZzEkVGltZSksIHkgPSBtZWFuX3BwX3NlZzFbW3BdXSwgeWVuZCA9IG1lYW5fcHBfc2VnMVtbcF1dLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgeWF4aXMgPSAieTIiLCBuYW1lPSJBdmcuIFBQICgxc3QgcGFydCkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lPWxpc3QoY29sb3I9InJlZCIsIGRhc2ggPSAnZG90JykpICU+JQogICAgYWRkX3NlZ21lbnRzKHggPSBtaW4ocERhdGFfc2VnMiRUaW1lKSwgeGVuZCA9IG1heChwRGF0YV9zZWcyJFRpbWUpLCB5ID0gbWVhbl9wcF9zZWcyW1twXV0sIHllbmQgPSBtZWFuX3BwX3NlZzJbW3BdXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHlheGlzID0gInkyIiwgbmFtZT0iQXZnLiBQUCAoMm5kIHBhcnQpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZT1saXN0KGNvbG9yPSJncmVlbiIsIGRhc2ggPSAnZG90JykpICU+JQogICAgYWRkX3NlZ21lbnRzKHggPSBtaW4ocERhdGFfc2VnMyRUaW1lKSwgeGVuZCA9IG1heChwRGF0YV9zZWczJFRpbWUpLCB5ID0gbWVhbl9wcF9zZWczW1twXV0sIHllbmQgPSBtZWFuX3BwX3NlZzNbW3BdXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHlheGlzID0gInkyIiwgbmFtZT0iQXZnLiBQUCAoM3JkIHBhcnQpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZT1saXN0KGNvbG9yPSJibHVlIiwgZGFzaCA9ICdkb3QnKSkgJT4lCiAgICBhZGRfc2VnbWVudHMoeCA9IG1pbihwRGF0YV9zZWc0JFRpbWUpLCB4ZW5kID0gbWF4KHBEYXRhX3NlZzQkVGltZSksIHkgPSBtZWFuX3BwX3NlZzRbW3BdXSwgeWVuZCA9IG1lYW5fcHBfc2VnNFtbcF1dLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgeWF4aXMgPSAieTIiLCBuYW1lPSJBdmcuIFBQICg0dGggcGFydCkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lPWxpc3QoY29sb3I9InB1cnBsZSIsIGRhc2ggPSAnZG90JykpICU+JQogICAgbGF5b3V0KAogICAgICB0aXRsZT1wYXN0ZTAoIlN1YmplY3QgIyIsIHApLCAKICAgICAgeGF4aXM9bGlzdCh0aXRsZT0iVGltZSBbc10iLCByYW5nZT1jKDApKSwgCiAgICAgIHlheGlzPXkxLCAKICAgICAgeWF4aXMyPXkyLCAKICAgICAgbWFyZ2luID0gbGlzdChsID0gNTAsIHIgPSA1MCwgYiA9IDUwLCB0ID0gNTAsIHBhZCA9IDQpLAogICAgICBsZWdlbmQgPSBsaXN0KHggPSAwLjUsIHhhbmNob3IgPSAiY2VudGVyIiwgeSA9IDAuMiwgYmdjb2xvciA9ICJyZ2JhKDAsMCwwLDApIiwgdGl0bGU9Ik1ldHJpYyIsIG9yaWVudGF0aW9uID0gImgiKSwKICAgICAgYXV0b3NpemUgPSBGCiAgICApCiAgCiAgcGx0X0FsbEFjY1tbcF1dIDwtIHBsb3RfQWNjCn0KCgpodG1sdG9vbHM6OnRhZ0xpc3QocGx0X0FsbEFjYykKYGBgCgoKYGBge3J9Ck5VTUJFUl9PRl9DTFVTVEVSUyA9IDMKCmNvbG9yX2RhcmtwaW5rID0gIiNlNzU0ODAiCkNMVVNURVJfQlJBTkNIX0NPTE9SUyA8LSBjKCJibHVlIiwgImRhcmtyZWQiLCBjb2xvcl9kYXJrcGluaywgImJsYWNrIilbMTpOVU1CRVJfT0ZfQ0xVU1RFUlNdCkNMVVNURVJfTEFCRUxfQ09MT1JTIDwtIGMoImJsdWUiLCAiZGFya3JlZCIsIGNvbG9yX2RhcmtwaW5rLCAiYmxhY2siKVsxOk5VTUJFUl9PRl9DTFVTVEVSU10KCmRmUFAgPC0gYXMuZGF0YS5mcmFtZShjYmluZCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9zZWcwKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9zZWcxKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9zZWcyKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9zZWczKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9zZWc0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX21heCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX3NlZzApLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfc2VnMSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9zZWcyKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX3NlZzMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfc2VnNCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX21heCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9zZWcwXzEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfc2VnMF8yKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX3NlZzBfMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9zZWcwXzQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9zZWcwXzEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9zZWcwXzIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9zZWcwXzMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9zZWcwXzQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfSGlnaEFjYyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9Mb3dBY2MpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9IaWdoQWNjKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfTG93QWNjKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX0hpZ2hBY2MxKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX0xvd0FjYzEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9IaWdoQWNjMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX0xvd0FjYzEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfSGlnaEFjYzIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KG1lYW5fcHBfTG93QWNjMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX0hpZ2hBY2MyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfTG93QWNjMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9IaWdoQWNjMyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3QobWVhbl9wcF9Mb3dBY2MzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChzdGRfcHBfSGlnaEFjYzMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9Mb3dBY2MzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX0hpZ2hBY2M0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVubGlzdChtZWFuX3BwX0xvd0FjYzQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5saXN0KHN0ZF9wcF9IaWdoQWNjNCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmxpc3Qoc3RkX3BwX0xvd0FjYzQpCiAgICAgICAgICAgICAgICAgICAgKSkKCm5hbWVzKGRmUFApIDwtIGMoIk1lYW5QUCIsICJTdGRQUCIsIAogICAgICAgICAgICAgICAgICJNZWFuUFBfU2VnMCIsICJNZWFuUFBfU2VnMSIsICJNZWFuUFBfU2VnMiIsICJNZWFuUFBfU2VnMyIsICJNZWFuUFBfU2VnNCIsICJNZWFuUFBfU2VnTWF4IiwKICAgICAgICAgICAgICAgICAiU3RkUFBfU2VnMCIsICJTdGRQUF9TZWcxIiwgIlN0ZFBQX1NlZzIiLCAiU3RkUFBfU2VnMyIsICJTdGRQUF9TZWc0IiwgIlN0ZFBQX1NlZ01heCIsCiAgICAgICAgICAgICAgICAgIk1lYW5QUF9TZWcwXzEiLCAiTWVhblBQX1NlZzBfMiIsICJNZWFuUFBfU2VnMF8zIiwgIk1lYW5QUF9TZWcwXzQiLAogICAgICAgICAgICAgICAgICJTdGRQUF9TZWcwXzEiLCAiU3RkUFBfU2VnMF8yIiwgIlN0ZFBQX1NlZzBfMyIsICJTdGRQUF9TZWcwXzQiLAogICAgICAgICAgICAgICAgICJNZWFuUFBfQWNjSGlnaCIsICIgTWVhblBQX0FjY0xvdyIsICJTdGRQUF9BY2NIaWdoIiwgIlN0ZFBQX0FjY0xvdyIsCiAgICAgICAgICAgICAgICAgIk1lYW5QUF9BY2NIaWdoMSIsICIgTWVhblBQX0FjY0xvdzEiLCAiU3RkUFBfQWNjSGlnaDEiLCAiU3RkUFBfQWNjTG93MSIsCiAgICAgICAgICAgICAgICAgIk1lYW5QUF9BY2NIaWdoMiIsICIgTWVhblBQX0FjY0xvdzIiLCAiU3RkUFBfQWNjSGlnaDIiLCAiU3RkUFBfQWNjTG93MiIsCiAgICAgICAgICAgICAgICAgIk1lYW5QUF9BY2NIaWdoMyIsICIgTWVhblBQX0FjY0xvdzMiLCAiU3RkUFBfQWNjSGlnaDMiLCAiU3RkUFBfQWNjTG93MyIsCiAgICAgICAgICAgICAgICAgIk1lYW5QUF9BY2NIaWdoNCIsICIgTWVhblBQX0FjY0xvdzQiLCAiU3RkUFBfQWNjSGlnaDQiLCAiU3RkUFBfQWNjTG93NCIpCgpiZWhhdmlvcmFsTWF0cml4Q2x1c3RlcmluZyA8LSBhcy5tYXRyaXgoZGZQUCkKCmRpc3RNYXRyaXggPC0gZGlzdChiZWhhdmlvcmFsTWF0cml4Q2x1c3RlcmluZykKaHJlc3VsdHMgPC0gZGlzdE1hdHJpeCAlPiUgaGNsdXN0KG1ldGhvZD0iYXZlcmFnZSIpCgpoYyA8LSBocmVzdWx0cyAlPiUgCiAgICAgIGFzLmRlbmRyb2dyYW0gJT4lCiAgICAgIHNldCgibm9kZXNfY2V4IiwgTlVNQkVSX09GX0NMVVNURVJTKSAlPiUKICAgICAgc2V0KCJsYWJlbHNfY29sIiwgdmFsdWUgPSBDTFVTVEVSX0xBQkVMX0NPTE9SUywgaz1OVU1CRVJfT0ZfQ0xVU1RFUlMpICU+JQogICAgICAjIHNldCgibGVhdmVzX3BjaCIsIDE5KSAlPiUKICAgICAgIyBzZXQoImxlYXZlc19jb2wiLCB2YWx1ZSA9IGMoImdyYXkiKSwgaz1OVU1CRVJfT0ZfQ0xVU1RFUlMpICU+JSAgICAKICAgICAgc2V0KCJicmFuY2hlc19rX2NvbG9yIiwgdmFsdWU9Q0xVU1RFUl9CUkFOQ0hfQ09MT1JTLCBrPU5VTUJFUl9PRl9DTFVTVEVSUykKCnBsb3QoaGMpCmxlZ2VuZCgidG9wcmlnaHQiLCAKICAgICB0aXRsZT0iRHJpdmU9TW90b3JpYyBcbkhpZXJhY2hpY2FsIENsdXN0ZXJpbmciLAogICAgIGxlZ2VuZCA9IGMoIkdyb3VwIDEiLCAiR3JvdXAgMiIsICJHcm91cCAzIiksIAogICAgIGNvbCA9IGMoImRhcmtyZWQiLCAicGluayIgLCAiYmx1ZSIpLAogICAgIHBjaCA9IGMoMjAsMjAsMjApLCBidHkgPSAibiIsICBwdC5jZXggPSAxLjUsIGNleCA9IDAuOCAsIAogICAgIHRleHQuY29sID0gImJsYWNrIiwgaG9yaXogPSBGQUxTRSwgaW5zZXQgPSBjKDAuNCwgMC4xKSkKYGBgCgojIENsdXN0ZXJpbmcgd2l0aCBTRCBvZiBQUApgYGB7cn0KbGlicmFyeShkZW5kZXh0ZW5kKQoKY2x1c3RlcmluZ0RmIDwtIGRmUFAgJT4lIHNlbGVjdChTdGRQUCkKTlVNQkVSX09GX0NMVVNURVJTID0gMwoKY29sb3JfZGFya3BpbmsgPSAiI2U3NTQ4MCIKQ0xVU1RFUl9CUkFOQ0hfQ09MT1JTIDwtIGMoImRhcmtyZWQiLCAiYmx1ZSIsICJyZWQiKVsxOk5VTUJFUl9PRl9DTFVTVEVSU10KQ0xVU1RFUl9MQUJFTF9DT0xPUlMgPC0gYygiZGFya3JlZCIsICJibHVlIiwgInJlZCIpWzE6TlVNQkVSX09GX0NMVVNURVJTXQoKYmVoYXZpb3JhbE1hdHJpeENsdXN0ZXJpbmcgPC0gYXMubWF0cml4KGNsdXN0ZXJpbmdEZikKcm93bmFtZXMoYmVoYXZpb3JhbE1hdHJpeENsdXN0ZXJpbmcpIDwtIHBhc3RlMCgiIyIsIHBlcnNvbnMpCmRpc3RNYXRyaXggPC0gZGlzdChiZWhhdmlvcmFsTWF0cml4Q2x1c3RlcmluZykKaHJlc3VsdHMgPC0gZGlzdE1hdHJpeCAlPiUgaGNsdXN0CgpoYyA8LSBocmVzdWx0cyAlPiUgCiAgICAgIGFzLmRlbmRyb2dyYW0gJT4lCiAgICAgIHNldCgibm9kZXNfY2V4IiwgTlVNQkVSX09GX0NMVVNURVJTKSAlPiUKICAgICAgc2V0KCJsYWJlbHNfY29sIiwgdmFsdWUgPSBDTFVTVEVSX0xBQkVMX0NPTE9SUywgaz1OVU1CRVJfT0ZfQ0xVU1RFUlMpICU+JQogICAgICAjIHNldCgibGVhdmVzX3BjaCIsIDE5KSAlPiUKICAgICAgIyBzZXQoImxlYXZlc19jb2wiLCB2YWx1ZSA9IGMoImdyYXkiKSwgaz1OVU1CRVJfT0ZfQ0xVU1RFUlMpICU+JSAgICAKICAgICAgc2V0KCJicmFuY2hlc19rX2NvbG9yIiwgdmFsdWU9Q0xVU1RFUl9CUkFOQ0hfQ09MT1JTLCBrPU5VTUJFUl9PRl9DTFVTVEVSUykKCnBsb3QoaGMpCmxlZ2VuZCgidG9wcmlnaHQiLCAKICAgICB0aXRsZT0iRHJpdmU9TW90b3JpYyBcbkNoYW5nZSBvZiBBcm91c2FsIiwKICAgICBsZWdlbmQgPSBjKCJFeGNlcHRpb25hbCBTRCIgLCAiTG93IFNEIiAsICJIaWdoIFNEIiksIAogICAgIGNvbCA9IGMoImRhcmtyZWQiLCAiYmx1ZSIgLCAicmVkIiksCiAgICAgcGNoID0gYygyMCwyMCwyMCksIGJ0eSA9ICJuIiwgIHB0LmNleCA9IDEuNSwgY2V4ID0gMC44ICwgCiAgICAgdGV4dC5jb2wgPSAiYmxhY2siLCBob3JpeiA9IEZBTFNFLCBpbnNldCA9IGMoMC4wLCAwLjEpKQpgYGAKCmBgYHtyfQpsaWJyYXJ5KGNsdXN0ZXIpCnNpbGhvdWV0dGVfc2NvcmUgPC0gZnVuY3Rpb24oayl7CiAga20gPC0ga21lYW5zKGNsdXN0ZXJpbmdEZiwgY2VudGVycyA9IGssIG5zdGFydD0yNSkKICBzcyA8LSBzaWxob3VldHRlKGttJGNsdXN0ZXIsIGRpc3QoY2x1c3RlcmluZ0RmKSkKICBtZWFuKHNzWywgM10pCn0KayA8LSAyOjEwCmF2Z19zaWwgPC0gc2FwcGx5KGssIHNpbGhvdWV0dGVfc2NvcmUpCnBsb3QoaywgdHlwZT0nYicsIGF2Z19zaWwsIHhsYWI9J051bWJlciBvZiBjbHVzdGVycycsIHlsYWI9J0F2ZXJhZ2UgU2lsaG91ZXR0ZSBTY29yZXMnLCBmcmFtZT1GQUxTRSkKYGBgCgpgYGB7cn0KIyBTdG9yZSBjbHVzdGVyaW5nIGRhdGEKZlBhdGggPC0gc3RyX2ludGVycCgiLi4vZGF0YS9wcm9jZXNzZWQvYW5hbHlzaXMvVFQxX0RyaXZlXzNfUFAuY3N2IikKZGZ4IDwtIGRmUFAKZGZ4IDwtIGNiaW5kKHBlcnNvbnMsIGRmeCkKbmFtZXMoZGZ4KSA8LSBjKCJTdWJqZWN0IiAsIG5hbWVzKGRmUFApKQp3cml0ZS5jc3YoZGZ4LCBmUGF0aCwgcm93Lm5hbWVzID0gRikKYGBgCgoK